package com.trs.progress.button;

import android.annotation.TargetApi;
import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Bitmap;
import android.graphics.Canvas;
import android.graphics.Paint;
import android.os.Build;
import android.util.AttributeSet;
import android.widget.Button;

import java.util.Arrays;

/**
 * Created by tangrisheng on 2016/5/23.
 * progress button
 */
public class ProgressButton extends Button {

    private static final String TAG = ProgressButton.class.getSimpleName();


    private int PROGRESS_COLOR_DEFAULT;
    private int PROGRESS_WIDTH_DEFAULT = 50;
    private static final int PROGRESS_STEP_NORMAL = 5;
    private static final int PROGRESS_STEP_FAST = 10;
    private static final int PROGRESS_STEP_SLOW = 2;

    private static final int PROGRESS_SPACE = 50; // progress left space

    private int progressColor = -1;
    private float progressWidth = -1;
    private Paint paint;
    private int progressOffset;
    private int progressStep;
    private Bitmap progressBitmap;

    private boolean isLoading;

    public ProgressButton(Context context) {
        super(context);
    }

    public ProgressButton(Context context, AttributeSet attrs) {
        super(context, attrs);
        init(context, attrs);
    }

    public ProgressButton(Context context, AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    @TargetApi(Build.VERSION_CODES.LOLLIPOP)
    public ProgressButton(Context context, AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    void init(Context context, AttributeSet attrs) {
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            PROGRESS_COLOR_DEFAULT = getResources().getColor(android.R.color.darker_gray, null);
        } else {
            PROGRESS_COLOR_DEFAULT = getResources().getColor(android.R.color.darker_gray);
        }
        progressWidth = PROGRESS_WIDTH_DEFAULT;
        paint = new Paint();
        isLoading = false;
        initAttrs(context, attrs);
    }

    void initAttrs(Context context, AttributeSet attributeSet) {
        TypedArray typedArray = context.obtainStyledAttributes(attributeSet, R.styleable.progressButton);
        progressColor = typedArray.getColor(R.styleable.progressButton_progress_color, PROGRESS_COLOR_DEFAULT);
        progressWidth = typedArray.getDimension(R.styleable.progressButton_progress_width, PROGRESS_WIDTH_DEFAULT);
        int progressSpeed = typedArray.getInt(R.styleable.progressButton_progress_speed, 1);
        if (progressSpeed == 0) {
            progressStep = PROGRESS_STEP_FAST;
        } else if (progressSpeed == 1) {
            progressStep = PROGRESS_STEP_NORMAL;
        } else if (progressSpeed == 2) {
            progressStep = PROGRESS_STEP_SLOW;
        }
        typedArray.recycle();
    }

    void initProgressBitmap() {
        if (progressBitmap == null) {
            int[] pixs = new int[(int) (progressWidth * getHeight())];
            Arrays.fill(pixs, progressColor);
//            progressBitmap = Bitmap.createBitmap((int) progressWidth, getHeight(), Bitmap.Config.ARGB_8888);
            progressBitmap = Bitmap.createBitmap(pixs, (int) progressWidth, getHeight(), Bitmap.Config.ARGB_8888);
        }
    }

    @Override
    protected void onSizeChanged(int w, int h, int oldw, int oldh) {
        super.onSizeChanged(w, h, oldw, oldh);
        initProgressBitmap();
    }

    @Override
    protected void onDraw(Canvas canvas) {

        if (isLoading) {

            if (progressColor == -1) {
                paint.setColor(PROGRESS_COLOR_DEFAULT);
            } else {
                paint.setColor(progressColor);
            }
            int bottom = getHeight();
            if (progressOffset > getWidth()) {
                // offset > button width, draw progress from the beginning.
                resetProgressOffset();
            }
            int right = (int) (progressOffset + progressWidth);
            if (right > getWidth()) {
                // end of the progress > button width
                right = getWidth();
            }
            if (right < 0) {
//                Log.i(TAG, "don't draw");
            } else {
                if (right > progressOffset) {
//                    canvas.drawRect(progressOffset, 0, right, bottom, paint);
                    if (!progressBitmap.isRecycled()) {
                        canvas.drawBitmap(progressBitmap, progressOffset, 0, null);
                    } else {
                        isLoading = false;
                    }
                } else {
                    // right > left, do not draw
//                    Log.i(TAG, "don't draw");
                }
            }

            progressOffset += progressStep;
            postInvalidateOnAnimation();
        }

        super.onDraw(canvas);
    }


    public void startLoading() {
        isLoading = true;
        resetProgressOffset();
        invalidate();
    }

    public void stopLoading() {
        isLoading = false;
        resetProgressOffset();
        invalidate();
    }

    public boolean isLoading() {
        return isLoading;
    }

    private void resetProgressOffset() {
        progressOffset = (int) (-progressWidth - PROGRESS_SPACE);
    }

    @Override
    protected void finalize() throws Throwable {
        isLoading = false;
        if (progressBitmap != null && !progressBitmap.isRecycled()) {
            progressBitmap.recycle();
            progressBitmap = null;
        }
        super.finalize();
    }
}
